package com.example.t470p.facechecktickets.facesdk;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import cn.face.localsdkdemo.ConStant;
import cn.face.localsdkdemo.util.FileUtil;
import cn.face.localsdkdemo.util.ImgUtil;
import cn.face.localsdkdemo.util.PreferencesUtils;

/**
 * Created by zhaodianbo on 2018-3-21.
 */
public class FaceSDKImplV2 implements IFaceSDK {
    Context mContext;
    String[] models;
    private static final String PREV_VERSION_CODE = "prev_version_code";
    private static FaceSDKImplV2 faceSDKImplV2;
    IFaceV2Service iFaceV2Service;
    ServiceConnection serviceConnection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iFaceV2Service=IFaceV2Service.Stub.asInterface(service);
            synchronized (this){
                notify();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private FaceSDKImplV2(){}


    public static IFaceSDK getInstance() {
        if(faceSDKImplV2==null){
            faceSDKImplV2=new FaceSDKImplV2();
        }
        return faceSDKImplV2;
    }

    @Override
    public int init(Context context) {
        mContext=context;

        Intent bindIntent = new Intent(mContext, FaceServiceV2.class);
        mContext.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);


        int versionCode = getVersionCode(mContext);
        int prevVersionCode = PreferencesUtils.getInt(mContext, PREV_VERSION_CODE,
                versionCode);
        try {
            models = mContext.getAssets().list(ConStant.ASSERT_MODULE_DIR);
            int ret=copyModules(versionCode, prevVersionCode);

            PreferencesUtils.putInt(mContext, PREV_VERSION_CODE, versionCode);
            if(ret==0){
                synchronized (this){
                    wait(2000);
                }
                return iFaceV2Service.init();
            }
        }catch (RemoteException re){
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return -1;
    }

    private void reconnectService(){
        iFaceV2Service=null;
        mContext.unbindService(serviceConnection);
        serviceConnection=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                iFaceV2Service=IFaceV2Service.Stub.asInterface(service);
                try {
                    iFaceV2Service.init();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void onServiceDisconnected(ComponentName name) {
            }
        };
        Intent bindIntent = new Intent(mContext, FaceServiceV2.class);
        mContext.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }


    @Override
    public Object getIDCardPhotoFeature(Bitmap bitmapIDCardPhoto) {
        if(iFaceV2Service==null) return null;
        byte[] idcardPhotoBytes = ImgUtil.bitmapToByte(bitmapIDCardPhoto, Bitmap.CompressFormat.JPEG, 100);
        try {
            return iFaceV2Service.getIDCardPhotoFeature(idcardPhotoBytes);
        } catch (RemoteException e) {
            e.printStackTrace();
            reconnectService();
        }
        return null;
    }

    @Override
    public Object getPresentPhotoFeature(Bitmap bitmapPresentPhoto) {
        if(iFaceV2Service==null) return null;
        byte[] imgBytes = ImgUtil.bitmapToByte(bitmapPresentPhoto, Bitmap.CompressFormat.JPEG, 90);
        try {
            return iFaceV2Service.getPresentPhotoFeature(imgBytes);
        } catch (RemoteException e) {
            e.printStackTrace();
            reconnectService();
        }
        return null;
    }

    @Override
    public int compareFeature(Object idcardPhotoFea, Object presentPhotoFea) {
        if(iFaceV2Service==null) return 0;
        try {
            return iFaceV2Service.compareFeature((byte[]) idcardPhotoFea,(byte[]) presentPhotoFea);
        } catch (RemoteException e) {
            e.printStackTrace();
            reconnectService();
        }
        return 0;
    }

    @Override
    public int deinit() {
        try {
            if(iFaceV2Service!=null)
                iFaceV2Service.deinit();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        mContext.unbindService(serviceConnection);
/*        try{
            mFaceSDK.DestoryHandles();
        }catch (Exception e){}*/
        return 0;
    }



    // 拷贝assets下的文件的方法
    private void assetsDataToSD(String assertDir, String fileName,
                                String modelDir) throws IOException {

        String outputPath = modelDir + File.separator + fileName;
        InputStream myInput;
        OutputStream myOutput = new FileOutputStream(outputPath);

        String assertFilePath = assertDir + File.separator + fileName;
        myInput = mContext.getAssets().open(assertFilePath);
        byte[] buffer = new byte[1024];
        int length = myInput.read(buffer);
        while (length > 0) {
            myOutput.write(buffer, 0, length);
            length = myInput.read(buffer);
        }

        myOutput.flush();
        myInput.close();
        myOutput.close();
    }




    private String getInfo() {

        String mtype = Build.MODEL;// MI 4W
        String mtyb = Build.BRAND;// Xiaomi

        return mtype + mtyb;
    }

    /**
     * 检查模型是否缺失
     *
     * @param models
     * @param modelDir
     * @return false 模型缺少 true 不缺失
     */
    public boolean checkModels(String[] models, String modelDir) {

        for (String str : models) {
            File file = new File(modelDir + File.separator + str);
            if (!file.exists() || file.length() == 0)
                return false;
        }
        return true;
    }

    // 预加载CWModels数据
    public int  copyModules(int versionCode, int prevVersionCode) {

        // 检测模型是否存在以及程序verisonCode是否不一样
        if (!checkModels(models, ConStant.sModelDir)
                || versionCode != prevVersionCode) {
            // 从assets复制模型文件到指定路劲
            FileUtil.mkDir(ConStant.sModelDir);
            for (int i = 0; i < models.length; i++) {
                try {
                    assetsDataToSD(ConStant.ASSERT_MODULE_DIR,
                            models[i], ConStant.sModelDir);//
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (!checkModels(models, ConStant.sModelDir)) {
                return -1;
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    public int getVersionCode(Context context)// 获取版本号(内部识别号)
    {
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            return pi.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return 0;
        }
    }


}
